//
//  WCNConstantsCDStore.m
//  WCN
//
//  Created by 杨鑫 on 15/6/11.
//  Copyright (c) 2015年 ShanghaiCize Trade And Business Co., Ltd. All rights reserved.
//

#import "WCNConstantsCDStore.h"

@import CoreData;

@interface WCNConstantsCDStore ()

@property (strong, nonatomic) NSManagedObjectContext *context;
@property (strong, nonatomic) NSManagedObjectModel *model;

@end

@implementation WCNConstantsCDStore

#pragma mark - Create

+ (instancetype)shareStore
{
    static WCNConstantsCDStore *store = nil;
    //block
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        store = [[WCNConstantsCDStore alloc] initPrivate];
    });
    return store;
}

- (instancetype)init
{
    @throw [NSException exceptionWithName:@"Singleton"
                                   reason:@"Use + [WCNConstantsCDStore shareStore]"
                                 userInfo:nil];
    return nil;
}

- (instancetype)initPrivate
{
    self = [super init];
    if (self) {
        //创建模型，被协调器使用
        _model = [[NSManagedObjectModel alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ConstantsModels" withExtension:@"momd"]];
        
        //创建协调器, 直接操作存储文件的对象
        NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_model];
        NSURL *storeURL = [NSURL fileURLWithPath:[self path]];
        NSError *error = nil;
        
        //要考虑到，core data随着app升级以后,实体被修改的问题
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                 [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
        
        if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
            @throw [NSException exceptionWithName:@"OpenFailure" reason:[error localizedDescription] userInfo:nil];
        }
        
        //创建上下文，调用协调器
        _context = [[NSManagedObjectContext alloc] init];
        _context.persistentStoreCoordinator = psc;
    }
    return self;
}

#pragma mark - Hospital

- (NSArray *)createHospitals:(NSArray *)data
{
    return [self insertEntity:@"Hospital" withArray:data overWrite:YES withPredicate:nil];
}

- (NSArray *)getHospitals
{
    NSArray *hospitals = [self findAllEntity:@"Hospital" withSort:nil withPredicate:nil];
    
    return [hospitals sortedArrayUsingComparator:^(Hospital *hospital1, Hospital *hospital2){
        NSInteger value = [hospital1.stringId integerValue] - [hospital2.stringId integerValue] ;
        if (value > 0) {
            return NSOrderedDescending;
        } else if (value < 0) {
            return NSOrderedAscending;
        }
        return NSOrderedSame;
    }];
}

#pragma mark - Ward

- (NSArray *)createWards:(NSArray *)data hospital:(NSString *)hospitalId
{
    return [self insertEntity:@"Ward" withArray:data overWrite:YES withPredicate:[NSPredicate predicateWithFormat:@"hospitalId = %@", hospitalId]];
}

- (NSArray *)getWardsByhospital:(NSString *)hospitalId
{
    NSArray *wards = [self findAllEntity:@"Ward" withSort:nil withPredicate:[NSPredicate predicateWithFormat:@"hospitalId = %@", hospitalId]];
    
    return [wards sortedArrayUsingComparator:^(Ward *ward1, Ward *ward2){
        NSInteger value = [ward1.stringId integerValue] - [ward2.stringId integerValue] ;
        if (value > 0) {
            return NSOrderedDescending;
        } else if (value < 0) {
            return NSOrderedAscending;
        }
        return NSOrderedSame;
    }];
}

#pragma mark - NurseDetail

- (NSArray *)createNurses:(NSArray *)data hospital:(NSString *)hospitalId
{
    return [self insertEntity:@"NurseDetail" withArray:data overWrite:YES withPredicate:[NSPredicate predicateWithFormat:@"hospitalId = %@", hospitalId]];
}

- (NSArray *)getNursesByhospital:(NSString *)hospitalId
{
    NSArray *wards = [self findAllEntity:@"NurseDetail" withSort:nil withPredicate:[NSPredicate predicateWithFormat:@"hospitalId = %@", hospitalId]];
    
    return [wards sortedArrayUsingComparator:^(NurseDetail *nurse1, NurseDetail *nurse2){
        NSInteger value = [nurse1.stringId integerValue] - [nurse2.stringId integerValue] ;
        if (value > 0) {
            return NSOrderedDescending;
        } else if (value < 0) {
            return NSOrderedAscending;
        }
        return NSOrderedSame;
    }];
}

#pragma mark - CareCase

- (NSArray *)createCareCases:(NSArray *)data
{
    return [self insertEntity:@"CareCase" withArray:data overWrite:YES withPredicate:nil];
}

- (NSArray *)getCareCases
{
    NSArray *carsCases = [self findAllEntity:@"CareCase" withSort:nil withPredicate:nil];
    
    return [carsCases sortedArrayUsingComparator:^(CareCase *careCase1, CareCase *careCase2){
        NSInteger value = [careCase1.stringId integerValue] - [careCase2.stringId integerValue] ;
        if (value > 0) {
            return NSOrderedDescending;
        } else if (value < 0) {
            return NSOrderedAscending;
        }
        return NSOrderedSame;
    }];
}

#pragma mark - Other

- (BOOL)saveData
{
    //一般插入时，马上保存一次；
    //其他更新操作，只在app后台运行时才保存
    
    NSError *error;
    BOOL success = [self.context save:&error];
    if (!success) {
        [NSException raise:@"Fetch fialed" format:@"Reason: %@", [error localizedDescription]];
    }
    return success;
}

- (void)removeAllData
{
    [self saveData];
    
    NSPersistentStoreCoordinator *psc = _context.persistentStoreCoordinator;
    NSArray *stores = [psc persistentStores];
    for(NSPersistentStore *store in stores) {
        [psc removePersistentStore:store error:nil];
        [[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:nil];
    }
    
    NSURL *storeURL = [NSURL fileURLWithPath:[self path]];
    NSError *error = nil;
    if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        @throw [NSException exceptionWithName:@"OpenFailure" reason:[error localizedDescription] userInfo:nil];
    }
}

#pragma mark - Private

- (id)createEntity:(NSString *)name insert:(BOOL)insert
{
    NSEntityDescription *entity = [NSEntityDescription entityForName:name inManagedObjectContext:self.context];
    NSManagedObject *managedEntity = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:insert?self.context:nil];
    
    return managedEntity;
}

- (NSArray *)insertEntity:(NSString *)name withArray:(NSArray *)list overWrite:(BOOL)is withPredicate:(NSPredicate *)predicate
{
    if (is) {
        //删除原来的数据
        NSArray *oldList = [self findAllEntity:name withSort:nil withPredicate:predicate];
        for (NSManagedObject *entity in oldList) {
            [self.context deleteObject:entity];
        }
    }
    
    NSMutableArray *entities = [[NSMutableArray alloc] init];
    for (NSDictionary *item in list) {
        NSManagedObject *entity = [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:self.context];
        [entity safeSetValuesForKeysWithDictionary:item];
        
        [entities addObject:entity];
    }
    
    return entities;
}

- (NSArray *)findAllEntity:(NSString *)name withSort:(NSArray *)sorts withPredicate:(NSPredicate *)predicate
{
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.entity = [NSEntityDescription entityForName:name inManagedObjectContext:self.context];
    request.predicate = predicate;
    
    if (!sorts) {
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"stringId" ascending:YES];
        sorts = @[sort];
    }
    request.sortDescriptors = sorts;
    
    NSError *error;
    NSArray *result = [self.context executeFetchRequest:request error:&error];
    if (!result) {
        [NSException raise:@"Fetch fialed" format:@"Reason: %@", [error localizedDescription]];
        return nil;
    }
    //result好像会弱引用查询的结果，save的时候使用
    return result;
}

- (id)findOneEntity:(NSString *)name withPredicate:(NSPredicate *)predicate
{
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.entity = [NSEntityDescription entityForName:name inManagedObjectContext:self.context];
    request.predicate = predicate;
    
    NSError *error;
    NSArray *result = [self.context executeFetchRequest:request error:&error];
    if (!result) {
        [NSException raise:@"Fetch fialed" format:@"Reason: %@", [error localizedDescription]];
        return nil;
    }
    
    if (result.count > 0) {
        return result[0];
    } else {
        return nil;
    }
}

#pragma mark - Path

- (NSString *)path
{
    NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    return [docs stringByAppendingPathComponent:@"constants.data"];
}

@end
